---
title: Native automation - usage
---

Once set up, interacting with the native UI using Patrol is very easy!

### Basics

After you've got your `NativeAutomator` object, you simply call methods on it
and it does the magic.

To tap on a native view (for example, a button in a WebView):

```dart
await $.native.tap(Selector(text: 'Sign up for newsletter'));
```

To enter text into a native view (for example, a form in a WebView):

```dart
await $.native.enterText(
  Selector(text: 'Enter your email'),
  text: 'charlie@root.me',
);
```

You can also enter text into n-th currently visible text field (counting from
0):

```dart
await $.native.enterTextByIndex('charlie_root', index: 0); // enter username
await $.native.enterTextByIndex('ny4ncat', index: 1); // enter password
```

The above are the simplest, most common actions, but they already make it
possible to test scenarios that were impossible to test before, such as
WebViews.

<Warning>
  To tap, enter text, or perform generally any UI interaction with a iOS app
  that is not your Flutter app under test, you need to pass its bundle
  identifier. For example, to tap on the plus button in the iPhone contacts app,
  use:

```dart
await $.native.tap(
  Selector(text: 'Add'),
  appId: 'com.apple.MobileAddressBook',
);
```

</Warning>

### Notifications

To open the notification shade:

```dart
await $.native.openNotifications();
```

To tap on the second notification:

```dart
await $.native.tapOnNotificationByIndex(1);
```

You can also tap on notification by its content:

```dart
await $.native.tapOnNotificationBySelector(
  Selector(textContains: 'Someone liked your recent post'),
);
```

<YouTube id="G0i6HEk0HQg" />

### Permissions

To handle the native permission request dialog:

```dart
await $.native.grantPermissionWhenInUse();
await $.native.grantPermissionOnlyThisTime();
await $.native.denyPermission();
```

<YouTube id="yC3sqpY5P_A" />

If the permission request dialog visible is the location dialog, you can also
select the accuracy:

```dart
await $.native.selectFineLocation();
await $.native.selectCoarseLocation();
```

<YouTube id="Wl2DyOy5e2U" />

The test will fail if the permission request dialog is not visible. You can
check if it is with:

```dart
if (await $.native.isPermissionDialogVisible()) {
  await $.native.grantPermissionWhenInUse();
}
```

By default, `isPermissionDialogVisible()` waits for a short amount of time and
then returns `false` if the dialog is not visible. To increase the timeout:

```dart
if (await $.native.isPermissionDialogVisible(timeout: Duration(seconds: 5))) {
  await $.native.grantPermissionWhenInUse();
}
```

<Warning>
  Patrol can handle permissions on iOS only if the device language is set to
  English (preferably US). That's because there's no way to refer to a specific
  view in a language-independent way (like resourceId on Android).

If you want to handle permissions on iOS device with non-English locale, do it
manually:

```dart
await $.native.tap(
  Selector(text: 'Allow'),
  appId: 'com.apple.springboard',
);
```

</Warning>

### More resources

To see more integration tests demonstrating Patrol's various features, check out
our [example app][example_app].

[example_app]: https://github.com/leancodepl/patrol/tree/master/packages/patrol/example